package com.camel.core.controller;

import cn.dev33.satoken.stp.StpUtil;
import com.camel.core.entity.BasePaginationEntity;
import com.camel.core.entity.IFilter;
import com.camel.core.entity.IParams;
import com.camel.core.entity.Result;
import com.camel.core.enums.EntityStatus;
import com.camel.core.exceptions.CustomException;
import com.camel.core.service.BaseCommonService;
import com.camel.core.utils.PaginationUtil;
import com.camel.core.utils.ResultUtil;
import com.github.pagehelper.PageInfo;
import org.springframework.http.HttpStatus;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <控制器基类>
 *
 * @author baily
 * @date 2019/7/11
 * @since 1.0
 **/
public abstract class BaseCommonController<M extends BasePaginationEntity> {

    public static final String ROLE_ADMIN = "admin";

    public static final String COMPANYID = "companyId";

    /**
     * 获取服务
     *
     * @return
     */
    abstract public BaseCommonService getiService();

    /**
     * 获取模块名称
     *
     * @return
     */
    abstract public String getMouduleName();

    @PostMapping("/index")
    public Result index(@RequestBody IParams params) {
        if (params.hasFilter(COMPANYID) && StpUtil.hasRole(ROLE_ADMIN)) {
            List<IFilter> filters = params.getFilters();
            ArrayList<IFilter> iFilters = new ArrayList<>();
            for (IFilter filter : filters) {
                if (!filter.getFieldName().equals(COMPANYID)) {
                    iFilters.add(filter);
                }
            }
            params.setFilters(iFilters);
        }
        PageInfo<BasePaginationEntity> basePaginationEntityPageInfo = PaginationUtil.startPage(params, () -> {
            getiService().list(params);
        });
        return ResultUtil.success(basePaginationEntityPageInfo);
    }

    /**
     * 获取详情
     *
     * @param id
     * @return
     */
    @GetMapping("/get")
    public Result details(@RequestParam("id") Serializable id) {
        Object obj = getiService().getById(id);
        if (ObjectUtils.isEmpty(obj)) {
            return ResultUtil.notFound();
        }
        return ResultUtil.success(obj);
    }

    /**
     * 保存
     *
     * @param entity
     * @return
     */
    @PostMapping
    public Result save(@RequestBody @Validated M entity) {
        if (exist(entity)) {
            return ResultUtil.error(500, getMouduleName() + "已存在");
        }
        // 设置边角料属性
        entity.setCreator(StpUtil.getLoginIdAsInt());
        entity.setUpdator(StpUtil.getLoginIdAsInt());
        entity.setUpdateAt(new Date());
        entity.setCreateAt(new Date());
        entity.setStatus(EntityStatus.NORMAL);

        boolean insert = getiService().save(entity);
        if (insert) {
            return ResultUtil.success("新增" + getMouduleName() + "成功");
        }
        return ResultUtil.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), "新增" + getMouduleName() + "失败");
    }

    /**
     * 更新
     *
     * @param entity
     * @return
     */
    @PostMapping("/update")
    public Result update(@RequestBody M entity) {
        entity.setUpdateAt(new Date());
        entity.setUpdator(StpUtil.getLoginIdAsInt());
        if (getiService().updateById(entity)) {
            return ResultUtil.success("修改" + getMouduleName() + "成功");
        }
        return ResultUtil.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), "修改" + getMouduleName() + "失败");
    }

    /**
     * 删除
     *
     * @param id 主键
     * @return
     */
    @DeleteMapping("/{id}")
    public Result delete(@PathVariable Serializable id) {
        if (deleteAble(id) && getiService().removeById(id)) {
            return ResultUtil.success("删除" + getMouduleName() + "成功");
        }
        return ResultUtil.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), "删除" + getMouduleName() + "失败");
    }

    @PostMapping("/all")
    public Result all() {
        return ResultUtil.success(getiService().list());
    }

    public boolean deleteAble(Serializable id) {
        Object detail = getiService().getById(id);
        if (ObjectUtils.isEmpty(detail)) {
            throw new CustomException("未发现目标对象");
        }
        return true;
    }

    /**
     * 判断是否重复
     *
     * @param entity
     * @return
     */
    public boolean exist(M entity) {
        return false;
    }


    /**
     * 获取业务KEY
     * 各个子类需要重写
     *
     * @return
     */
    public String getBusinessKey() {
        return "当使用到业务KEY的时候你必须重写这个方法！！";
    }

}
